package com.xp.record25.bio.nio.selector;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;

public class NioServer {

    public static void main(String[] args) throws IOException {
        Selector selector = Selector.open();
        ServerSocketChannel ssc = ServerSocketChannel.open();
        System.out.println("ssc = " + ssc);
        ssc.configureBlocking(false);
        ssc.bind(new InetSocketAddress(8888));
        //绑定 selectorkey 并注册感兴趣的事件
        SelectionKey sscKey = ssc.register(selector, SelectionKey.OP_ACCEPT, null);
        System.out.println("sscKey == "+ sscKey);

        while (true) {
            //阻塞等待事件发生
            System.out.println("阻塞等待事件发生");
            selector.select();
            //事件发生后，获取 selectingKey
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            System.out.println("selectionKeys.size() = " + selectionKeys.size());
            Iterator<SelectionKey> iterator = selectionKeys.iterator();
            while (iterator.hasNext()) {
                SelectionKey key = iterator.next();
                //获取到key 之后就将 key删除了，如果不处理则会引起无限循环
                iterator.remove();

                try {
                    //如果是连接事件
                    if (key.isAcceptable()) {
                        //如果是可读事件，则直接转换为 serverSocketChannel
                        ServerSocketChannel channel = (ServerSocketChannel) key.channel();
                        System.out.println("channel = " + channel);
                        //连接并得到客户端连接
                        SocketChannel sc = channel.accept();
                        System.out.println("sc = " + sc);
                        sc.configureBlocking(false);
                        //将客户端的 channel 也注册到 selector中
                        SelectionKey scKey = sc.register(selector, SelectionKey.OP_READ, null);
                        System.out.println("scKey = " + scKey);
                        //如果是读取事件
                    }else if (key.isReadable()) {
                        SocketChannel channel = (SocketChannel) key.channel();
                        System.out.println("readable   = = =  =channel = " + channel);
                        ByteBuffer buffer = ByteBuffer.allocate(16);
                        int read = channel.read(buffer);
                        if (-1  ==  read) {
                            key.cancel();
                        }else{
                            buffer.flip();
                            System.out.println("new String(buffer.array()).trim() = " + new String(buffer.array()).trim());
                        }

                    }
                } catch (IOException e) {
                    //连接被关闭异常，直接取消掉
                    key.cancel();
                    e.printStackTrace();
                }
            }

        }


    }
}
